package cn.nawang.ebeim.api.comm;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import cn.nawang.ebeim.api.domain.User;
import cn.nawang.ebeim.api.service.UserService;
import cn.nawang.ebeim.api.utils.ValidateUtil;

/**
 * @ClassName: UserLoginWebInterceptor
 * @Description: TODO
 * @author fanyb
 * @date Aug 12, 2015 10:40:52 AM
 * @version v1.0
 */
public class UserLoginWebInterceptor extends BaseController implements HandlerInterceptor {

//  @Autowired
//  private TokenManager tokenManager;
  @Autowired
  private UserService userService;

  public String[] allowIps;// 授信的ips地址

  public String[] allowUrls;// 还没发现可以直接配置不拦截的资源，所以在代码里面来排除

  public String[] tokenUrls;// 需要验证token的url

  public void setTokenUrls(String[] tokenUrls) {
    this.tokenUrls = tokenUrls;
  }

  public void setAllowUrls(String[] allowUrls) {
    this.allowUrls = allowUrls;
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
      Object handler, Exception ex) throws Exception {

  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
      ModelAndView modeView) throws Exception {
    // 在报文中添加用户登录的令牌

  }

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    try {
      String requestUrl = request.getRequestURI().replace(request.getContextPath(), "");
      // 固定ip地址是不需要token
      String requestIp = getIpAddress(request);

      // 判断是否需要token（true:需要，false不需要）
      boolean isNeedToken = isNeedToken(requestUrl);
      if (isNeedToken) {
        // 判断Token是否有效
        boolean isTokenEffective = validToken(request, response);
        if(!isTokenEffective){
          return false;
        }else{
          return true;
        }
      }
      // 判断是否需要登录(true:不需要，false:需要)
      boolean isNeedLogin = isNeedLogin(requestUrl);
      if (isNeedLogin) {
        return true;
      }
      // 测试时默认使用——用户名为benchi1的用户登录
//       User loginUser = userService.findOne("24");
//       this.setUserLoginInfo(request, loginUser);
      Object user = request.getSession().getAttribute("user");
      if (user == null) {
        request.getRequestDispatcher("/login/fail").forward(request, response);
        return false;
      }
      return true;
    } catch (Throwable e) {
      // 返回服务端处理错误指令
      return false;
    }
  }

  /**
   * 
   * @author fanyb
   * @Description: 判断是否需要登录
   * @param requestUrl
   * @return boolean
   * @date Nov 6, 20154:31:44 PM
   *
   * @修改人
   * @修改日期
   */
  private boolean isNeedLogin(String requestUrl) {
    try {
      if (null != allowUrls && allowUrls.length >= 1) {
        for (String url : allowUrls) {
          if (requestUrl.contains(url)) {
            return true;
          }
        }
      }
    } catch (Throwable e) {
      // 返回服务端处理错误指令
      e.printStackTrace();
      return false;
    }
    return false;
  }

  /**
   * 
   * @author fanyb
   * @Description: 判断是否需要token
   * @param requestUrl
   * @return boolean
   * @date Nov 6, 20154:32:39 PM
   *
   * @修改人
   * @修改日期
   */
  private boolean isNeedToken(String requestUrl) {
    try {

      // 判断是否授信的请求
      if (null != allowIps && allowIps.length >= 1) {
        for (String url : allowUrls) {
          if (requestUrl.contains(url)) {
            return true;
          }
        }
      }

      // 不是授信的请求并且需要token
      if (null != tokenUrls && tokenUrls.length >= 1) {
        for (String url : tokenUrls) {
          if (requestUrl.contains(url)) {
            return true;
          }
        }
      }
    } catch (Throwable e) {
      // 返回服务端处理错误指令
      e.printStackTrace();
      return false;
    }
    return false;
  }

  /**
   * 
   * @author fanyb
   * @Description: token验证
   * @return boolean
   * @date Nov 6, 20157:10:00 PM
   *
   * @修改人
   * @修改日期
   */
  private boolean validToken(HttpServletRequest request, HttpServletResponse response) {
    String token=request.getParameter("token");
    if(!ValidateUtil.isEmpty(token)&&token.equals("tokennawang")){
      return true;
    }
    return false;
//    try {
//      tokenManager.findToken(token);
//      return true;
//    } catch (TokenException e) {
//      // 捕获到异常则，告诉客户端没有token
//      String json = "{\"code\":499,\"desc\":\"token已失效，请重新登录,获取可用token。\"}";
//      try {
//        response.getWriter().write(json);
//        response.getWriter().flush();
//        response.getWriter().close();
//      } catch (Exception ex) {
//        ex.printStackTrace();
//      }
//      e.printStackTrace();
//    }
//    return false;
  }

  /*
   * 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
   */
  private String getIpAddress(HttpServletRequest request) {
    try {

      String ip = request.getHeader("X-Forwarded-For");

      if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getHeader("Proxy-Client-IP");

        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getHeader("WL-Proxy-Client-IP");

        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getHeader("HTTP_CLIENT_IP");

        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getHeader("HTTP_X_FORWARDED_FOR");

        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
          ip = request.getRemoteAddr();

        }
      } else if (ip.length() > 15) {
        String[] ips = ip.split(",");
        for (int index = 0; index < ips.length; index++) {
          String strIp = (String) ips[index];
          if (!("unknown".equalsIgnoreCase(strIp))) {
            ip = strIp;
            break;
          }
        }
      }
      return ip;
    } catch (Throwable e) {
      return "UNKNOWN";
    }
  }
}
